package it.uni.bo.monitoring.service;
import it.uni.bo.monitoring.dispatcher.RawDataProcessing;
import it.uni.bo.monitoring.log.LazyInsertLogData;
import it.uni.bo.monitoring.protocol.server.DataObject;
import it.uni.bo.monitoring.protocol.server.DecomposingPacket;
import it.uni.bo.monitoring.protocol.server.UDPServer;
import it.uni.bo.monitoring.protocol.unmarshaller.EventInfo;
import it.uni.bo.monitoring.protocol.unmarshaller.LazyInsertEvent;
import it.uni.bo.monitoring.protocol.unmarshaller.analysis.DataAnalysis;
import it.uni.bo.monitoring.queue.LazyInsertRawData;
import it.uni.bo.monitoring.queue.LazyRemoveRawData;
import it.uni.bo.monitoring.service.MonitoringServiceInterface;
import it.uni.bo.monitoring.sla.MonitoringEvent;
import it.uni.bo.monitoring.sla.chain.availability.MonitoringReliability;
import it.uni.bo.monitoring.sla.chain.causality.MonitoringPattern;
import it.uni.bo.monitoring.sla.chain.latency.MonitoringLatency;
import it.uni.bo.monitoring.sla.chain.throughput.MonitoringThroughput;
import it.uni.bo.monitoring.sla.context.MonitoringComponent;
import it.uni.bo.monitoring.sla.parser.SlaBean;

import java.util.concurrent.LinkedBlockingQueue;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.jboss.ejb3.annotation.*;

@Service(objectName = "servicePOJO:service=MonitoringService") 
@Management(MonitoringServiceInterface.class)
@Depends ("jboss.jca:name=MySqlDS,service=DataSourceBinding")
public class MonitoringService implements MonitoringServiceInterface {  


	private UDPServer us;
	private SessionFactory  factory;

	public void create() throws Exception { 
			factory= new Configuration().configure("META-INF/hibernate.cfg.xml").buildSessionFactory();
			
			//SERVIZIO DI RIMOZIONE PERSISTENTE DI RAWDATA
			LinkedBlockingQueue<byte[]> rawDataToRemove = new LinkedBlockingQueue<byte[]>();
			new LazyRemoveRawData(rawDataToRemove, factory).start();
			
			//SERVIZIO DI DISTRIBUZIONE DEI DATI
			LinkedBlockingQueue<DataObject> rawData = new LinkedBlockingQueue<DataObject>();
			RawDataProcessing rdp = new RawDataProcessing(rawData, rawDataToRemove, new DecomposingPacket());

			MonitoringComponent mc,mc1;
	        mc1 = mc = new MonitoringPattern();
	        mc1 = mc1.setNext(new MonitoringThroughput());
	        mc1 = mc1.setNext(new MonitoringLatency());
	        mc1 = mc1.setNext(new MonitoringReliability());
	        String slaLanguageInUse=StaticFields.SLANG_LANGUAGE;
	        
	        SlaBean.addSlaLanguage(slaLanguageInUse, it.uni.bo.monitoring.sla.parser.slang.SlangBean.class);
	        
			//SERVIZIO DI INDIVIDUZIONE DELLE VIOLAZIONI DEGLI EVENTI
			LinkedBlockingQueue<EventInfo> eventData = new LinkedBlockingQueue<EventInfo>();
			new MonitoringEvent(eventData, rawDataToRemove, factory, mc, slaLanguageInUse).start();
			
			//SERVIZIO DI INSERIMENTO PERSISTENTE DI EVENTI
			LinkedBlockingQueue<DataObject> rawDataToEvent = new LinkedBlockingQueue<DataObject>();
			rdp.addQueue(rawDataToEvent);
			new LazyInsertEvent(rawDataToEvent, rawDataToRemove, eventData, new DataAnalysis(factory), factory).start();

		
			//SERVIZIO DI INSERIMENTO PERSISTENTE DI LOGDATA
			LinkedBlockingQueue<DataObject> rawDataToLogData = new LinkedBlockingQueue<DataObject>();
			rdp.addQueue(rawDataToLogData);
			new LazyInsertLogData(rawDataToLogData, factory).start();
		
			//AVVIO SERVIZIO DI DISTRIBUZIONE DEI DATI
			rdp.start();

			//SERVIZIO DI INSERIMENTO PERSISTENTE DI RAWDATA
			LinkedBlockingQueue<byte[]> udpPacketToRawData = new LinkedBlockingQueue<byte[]>();
			new LazyInsertRawData(udpPacketToRawData, rawData, factory).start();
	
			//SERVIZIO DI RICEZIONE DI PACCHETTI UDP
			us=new UDPServer(udpPacketToRawData);
			us.start();
	} 

	public void destroy() {    
		factory = null;
	}

} 

